// 本节内容
// 1. 同步模式和异步模式
// 2. 事件循环和消息队列
// 3. 异步编程的几种方式
// 4. Promise 异步方案、宏任务和微任务 队列
// 5. Generator异步方案、async/await 语法糖

// 单线程：js执行环境中负责执行代码的线程只有一个


// 同步任务
// console.log('global begin')

// function bar() {
//   console.log('bar task')
// }

// function foo() {
//   console.log('foo task')
//   bar()
// }

// foo()

// console.log('global end')

// 异步任务
// 1. 会先在调用栈中压入一个匿名的全局调用， 然后依次执行
// 2. 压栈 global begin 然后 弹栈 输出 global begin
// 3. 压栈 timer1， 因为有倒计时，会把倒计时器放入web Api中，然后弹栈
// 4. 压栈 timer2，也因为有倒计时，也会将倒计时放入web Api中，然后弹栈
// 5. 接着压栈 global end，然后弹栈，输出 global end
// 6. 这时候调用栈中已经没有函数，调用栈请空
// 7. 然后，even loop 开始执行(even loop 的作用就是监听调用栈和消息队列，当调用栈中清空的时候，会从消息队列中取出第一个函数) ， 因为timer2 时间短，所以会放入
//    消息队列第一位，timer1 放第二位
// 8. 接着压栈timer2，输出timer2 invoke ，因为内部还有一个倒计时，放入web Api中
// 9. 接着轮到timer1 压栈timer1，弹栈timer1 输出timer1 invoke,调用栈清空
// 10.even loop 取出消息队列中的inner invoke ，压栈放入调用栈中，接着弹栈输入inner invoke

console.log('global begin')

setTimeout(function timer1() {
  console.log('timer1 invoke')
}, 1800)

setTimeout(function timer2() {
  console.log('timer2 invoke')
  setTimeout(function inner() {
    console.log('inner invoke')
  }, 1000)
}, 1000)

console.log('global end')

//  'global begin' 'global end' 'timer2 invoke' 'timer1 invoke' 'inner invoke'


// Promise 执行顺序
// Pormise 会作为微任务在本轮的宏任务完成后直接执行